﻿package sala.components 
{
	import sala.components.events.ScrollingEvent;
	import flash.display.DisplayObject;
	import flash.display.Sprite;
	import flash.display.MovieClip;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.MouseEvent;
	import flash.geom.Rectangle;
	import gs.TweenLite;
	import gs.TweenMax;
	
	/**
	 * ...
	 * @author 
	 */
	public class VerScroll extends EventDispatcher
	{
		
		public var scrollFace:Sprite;
		public var scrollTrack:Sprite;
		public var content:Sprite;
		public var masked:Sprite;
		public var upBtn:DisplayObject;
		public var downBtn:DisplayObject;
		
		private var scrollRange:Number; 
		private var contentRange:Number; 
		private var startY:Number; 
		private var percent:Number; 
		
		private var duration:Number;
		private var upSpeed:Number;
		
		public var scrollDirection:int = -1; // 0: up, 1: down
		public var isInited:Boolean;

		public var mouseWheelEnable:Boolean = false;
		
		public function VerScroll(pContent:Sprite, pMask:Sprite, pScrollTrack:Sprite, pScrollFace:Sprite, pUpBtn:DisplayObject = null, pDownBtn:DisplayObject = null, faceHeight: Number = 5, minDuration:Number = 0, pUpSpeed:Number = 5, pMouseWheelEnable:Boolean = false ) {
			mouseWheelEnable = pMouseWheelEnable;
			content = pContent;
			masked = pMask;
			content.mask = masked;
			scrollTrack = pScrollTrack;
			scrollFace = pScrollFace;
			upBtn = pUpBtn;
			downBtn = pDownBtn;
			this.duration = minDuration;
			upSpeed = pUpSpeed;
		    if (!isInited) {
				startY = content.y;
			}
			//scrollRange = scrollTrack.height - scrollFace.height;
			scrollRange = scrollTrack.height - faceHeight;
			//contentRange = content.height - masked.height;
			contentRange = content.height - masked.height;
			
			
			if (contentRange <= 0) {
				content.y = startY;
				//scrollTrack.visible = false;
				//scrollFace.visible = false;
				
				//scrollTrack.mouseEnabled = false;
				scrollFace.mouseEnabled = false;
				
				
				if (downBtn) downBtn.visible = false;
				if (upBtn) upBtn.visible = false;
			} else {
				if (content.y < startY - contentRange) content.y = startY - contentRange;
				scrollFace.y = scrollTrack.y + ((startY - content.y) / contentRange) * scrollRange;
				//scrollTrack.visible = true;
				//scrollFace.visible = true;
				
				scrollFace.mouseEnabled = true;
				scrollFace.buttonMode = true;
				
				if (downBtn) downBtn.visible = true;
				if (upBtn) upBtn.visible = true;
				initEvents();
			}
			
			isInited = true;
		}
		
		public function reInited(heightContent:Number): void
		{
			if (isNaN(heightContent))
			{
				contentRange = content.height - masked.height;
				
			}
			else
			{
				contentRange = heightContent - masked.height;
			}
			
			
			if (contentRange <= 0) {
				content.y = startY;
				scrollTrack.visible = false;
				scrollFace.visible = false;
				if (downBtn) downBtn.visible = false;
				if (upBtn) upBtn.visible = false;
			} else {
				if (content.y < startY - contentRange) content.y = startY - contentRange;
				scrollFace.y = scrollTrack.y + ((startY - content.y) / contentRange) * scrollRange;
				scrollTrack.visible = true;
				scrollFace.visible = true;
				if (downBtn) downBtn.visible = true;
				if (upBtn) upBtn.visible = true;
				scrollFace.buttonMode = true;
			}
		}
		
		public function autoScroll(deltaY:Number): void
		{
			var pageInx:int = Math.floor((deltaY - masked.height) / masked.height) + 1;
			var tmpNum: Number = pageInx * masked.height * (scrollTrack.height - scrollFace.height) / contentRange + scrollTrack.y;
			//scrollFace.y = Math.min(tmpNum, (scrollTrack.height - scrollFace.height) + scrollTrack.y);
			//this.updateScroll();
			var coo_y: Number = Math.min(tmpNum, (scrollTrack.height - scrollFace.height) + scrollTrack.y);
			TweenLite.to(scrollFace, 0.5, { y:coo_y, onUpdate:updateScroll } );
		}
		private function updateScroll(): void {
			var perc: Number = (scrollFace.y - scrollTrack.y) / scrollRange;
			var newY:Number;
			if (percent != perc) {
				percent = perc;
			
				newY = Math.round(startY - percent * contentRange);
				if (duration > 0) duration = duration + Math.abs(newY - content.y) / 300;
				TweenMax.to(content, duration, { y: newY } )
				var event:ScrollingEvent = new ScrollingEvent(ScrollingEvent.SCROLLING);
				event.percent = percent;
				dispatchEvent(event);
			}
		}
		
		private function initEvents(): void {
			scrollFace.stage.addEventListener(Event.ENTER_FRAME, loop);
			if (upBtn) upBtn.addEventListener(MouseEvent.MOUSE_DOWN, upBtnMouseDownHdl);
			if (downBtn) downBtn.addEventListener(MouseEvent.MOUSE_DOWN, downBtnMouseDownHdl);
			scrollFace.addEventListener(MouseEvent.MOUSE_DOWN, scrollFaceMouseDownHdl);
			scrollFace.stage.addEventListener(MouseEvent.MOUSE_UP, stageMouseUpHdl);
			scrollFace.stage.addEventListener(MouseEvent.MOUSE_WHEEL, stageMouseWheelHdl);
		}
		
		private function loop(e:Event):void 
		{
			if (scrollDirection == -1) return;
			if (scrollDirection == 0) { // up
				if (scrollFace.y - upSpeed > scrollTrack.y) {
					scrollFace.y -= upSpeed;
				} else {
					scrollFace.y = scrollTrack.y;
				}
			}
			if (scrollDirection == 1) { // down
				if (scrollFace.y + upSpeed < scrollTrack.y + scrollRange) {
					scrollFace.y += upSpeed;
				} else {
					scrollFace.y = scrollTrack.y + scrollRange;
				}
			}
			updateScroll();
		}
		
		private function upBtnMouseDownHdl(e:MouseEvent):void 
		{
			scrollDirection = 0; // scrollUp
		}
		private function downBtnMouseDownHdl(e:MouseEvent):void 
		{
			scrollDirection = 1; // scrollDown
		}
		
		private function scrollFaceMouseDownHdl(e:MouseEvent):void 
		{
			scrollFace.startDrag(false, new Rectangle(scrollTrack.x, scrollTrack.y, 0, scrollRange));
			scrollFace.stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHdl);
		}
		
		private function mouseMoveHdl(e:MouseEvent):void 
		{
			updateScroll();
		}
		
		private function stageMouseUpHdl(e:MouseEvent):void 
		{
			if (!scrollFace.stage) return;
			scrollDirection = -1;
			scrollFace.stopDrag();
			scrollFace.stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHdl);
		}
		
		private function stageMouseWheelHdl(e:MouseEvent):void 
		{
			if (!mouseWheelEnable) return;
			var nexPos:Number = scrollFace.y - e.delta * 6;
			var maxPos:Number = scrollTrack.y + scrollRange;
			if (nexPos > maxPos) nexPos = maxPos;
			if (nexPos < scrollTrack.y) nexPos = scrollTrack.y;
			scrollFace.y = nexPos;
			updateScroll();
		}
		
		public function finalize(): void {
			scrollFace.stage.removeEventListener(Event.ENTER_FRAME, loop);
			if (upBtn) upBtn.removeEventListener(MouseEvent.MOUSE_DOWN, upBtnMouseDownHdl);
			if (downBtn) downBtn.removeEventListener(MouseEvent.MOUSE_DOWN, downBtnMouseDownHdl);
			scrollFace.removeEventListener(MouseEvent.MOUSE_DOWN, scrollFaceMouseDownHdl);
			scrollFace.stage.removeEventListener(MouseEvent.MOUSE_UP, stageMouseUpHdl);
			scrollFace.stage.removeEventListener(MouseEvent.MOUSE_WHEEL, stageMouseWheelHdl);
			scrollFace.stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHdl);
		}
	}
	
}